/**
 * 
 */
package pe.bf.extranet.dao.impl;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Blob;
import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.sql.DataSource;
import javax.sql.rowset.serial.SerialBlob;
import javax.sql.rowset.serial.SerialException;

import oracle.jdbc.OracleTypes;

import org.apache.log4j.Logger;

import pe.bf.base.dao.impl.BaseDAOImpl;
import pe.bf.base.types.OutParameter;
import pe.bf.domain.bean.Distrito;
import pe.bf.domain.bean.Empleado;
import pe.bf.domain.bean.Empresa;
import pe.bf.domain.bean.Moneda;
import pe.bf.domain.bean.SolicitudCreacion;
import pe.bf.domain.bean.TipoCuenta;
import pe.bf.domain.bean.TipoDocumento;
import pe.bf.domain.exceptions.DomainException;
import pe.bf.extranet.dao.SolicitudCreacionDAO;

/**
 * @author rfigueroa
 * 
 */
public class SolicitudCreacionDAOImpl extends BaseDAOImpl implements
		SolicitudCreacionDAO {

	Logger logger = Logger.getLogger(SolicitudCreacionDAOImpl.class);

	private static final String USP_CRE_SOLIC_CREACION = "{call PGK_SOLICITUDCREACION.USP_CRE_SOLIC_CREACION(?,?,?,?,?,?,?,?,?)}";
	private static final String USP_CRE_EMPLEADO = "{call PGK_SOLICITUDCREACION.USP_CRE_EMPLEADO(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)}";
	private static final String USP_ACT_SOLIC_CREACION = "{call PGK_SOLICITUDCREACION.USP_ACT_SOLIC_CREACION(?,?,?,?)}";
	private static final String USP_ELI_SOLIC_CREACION = "{call PGK_SOLICITUDCREACION.USP_ELI_SOLIC_CREACION(?)}";
	private static final String USP_LIS_SOLIC_CREACION = "{call PGK_SOLICITUDCREACION.USP_LIS_SOLIC_CREACION(?)}";
	private static final String USP_LIS_SOLIC_CREAC_EMPRESA = "{call PGK_SOLICITUDCREACION.USP_LIS_SOLIC_CREAC_EMPRESA(?,?)}";
	private static final String USP_LIS_DET_SOLIC_CREACION = "{call PGK_SOLICITUDCREACION.USP_LIS_DET_SOLIC_CREACION(?,?,?)}";

	/**
	 * 
	 * @param dataSource
	 */
	public SolicitudCreacionDAOImpl(DataSource dataSource) {
		super(dataSource);
	}

	@Override
	public List<String> createSolicitudCreacion(SolicitudCreacion solicitudCreacion)
			throws DomainException {
		List<String> errores=new ArrayList();
		try {
			Blob blob=new SerialBlob(solicitudCreacion.getAdjunto());
			solicitudCreacion.setIdSolicitudCreacion(invokeStoreProcedureGetId(USP_CRE_SOLIC_CREACION,
					solicitudCreacion.getNombreArchivo(),
					solicitudCreacion.getEmpresa().getIdEmpresa(),
					solicitudCreacion.getTipoCuenta().getIdTipocuenta(),
					solicitudCreacion.getUsuarioCreacion(),
					solicitudCreacion.getNroRegistros(), 
					solicitudCreacion.getMoneda().getIdMoneda(), 
					solicitudCreacion.getAdjunto(),
					solicitudCreacion.getFechaCreacionArchivo(),
					new OutParameter(OracleTypes.VARCHAR))
					); 
			
			errores=createDetalleSolicitudCreacion((List)solicitudCreacion.getListaEmpleados(),solicitudCreacion.getIdSolicitudCreacion(),solicitudCreacion.getEmpresa().getIdEmpresa());
			 
			return errores; 
		}catch (Exception e) {
			e.printStackTrace();
			errores.add("Error al grabar cabecera =" + e.getMessage());
			throw new DomainException(e);
		}
		finally{
			return errores;
		}
	}
	
	@Override
	public List<String>  createDetalleSolicitudCreacion(List<Empleado> detalle,long id,long empresa)
			throws DomainException {
			List<String> errores=new ArrayList();
			DateFormat df=new SimpleDateFormat("dd/MM/yyyy");
			for(Empleado empleado:detalle){
				System.out.println("a crear empleado");
				try {
					invokeStoreProcedure(USP_CRE_EMPLEADO, 
							id,
							empleado.getApellidonombre(),
							empleado.getDireccion(),
							empleado.getEstadocivil(),
							empleado.getNrocuenta(),
							empleado.getNrodocumento(),
							empleado.getOcupacion(),
							empleado.getSexo(),
							empleado.getTelefono(),
							empleado.getUbigeo(),
							empleado.getUsuariocreacion(),
							empleado.getDistrito(),
							empresa,
							empleado.getMoneda().getIdMoneda(),
							empleado.getTipocuenta().getIdTipocuenta(),
							empleado.getTipodocumento().getIdTipodocumento(),
							df.format(empleado.getFechanacimiento()));
				} catch (Exception e) {
					errores.add("Empleado "+empleado.getNrodocumento()+" con errror"+e.getMessage());
					e.printStackTrace();
				}
					
			}
			return errores;
			 
	}

	@Override
	public void actualizarSolicitudCreacion(SolicitudCreacion solicitudCreacion)
			throws DomainException {
		invokeStoreProcedure(USP_ACT_SOLIC_CREACION,
				solicitudCreacion.getIdSolicitudCreacion(),
				solicitudCreacion.getEstado(),
				solicitudCreacion.getUsuarioModificacion(),
				solicitudCreacion.getFechaEjecucionbf());
	}

	@Override
	public void eliminarSolicitudCreacion(SolicitudCreacion solicitudCreacion)
			throws DomainException {
		invokeStoreProcedure(USP_ELI_SOLIC_CREACION,
				solicitudCreacion.getIdSolicitudCreacion());
	}

	@Override
	public List<SolicitudCreacion> listarSolicitudCreacion()
			throws DomainException {

		ResultSet resultSet = invokeStoreProcedureRs(USP_LIS_SOLIC_CREACION,
				new OutParameter(OracleTypes.CURSOR));
		List<SolicitudCreacion> solicitudCreacionList = new ArrayList<SolicitudCreacion>();
		SolicitudCreacion solicitudCreacion=new SolicitudCreacion();
		try {
			while (resultSet.next()) {
				solicitudCreacion = new SolicitudCreacion();
				solicitudCreacion.setIdSolicitudCreacion(resultSet.getLong("ID_SOLICITUDCREACION"));
				solicitudCreacion.setEstado(resultSet.getString("ESTADO"));
				solicitudCreacion.setFechaCreacion(resultSet.getDate("FECHACREACION"));
				solicitudCreacion.setFechaEjecucionbf(resultSet.getDate("FECHAEJECUCIONBF"));
				solicitudCreacion.setNombreArchivo(resultSet.getString("NOMBREARCHIVO"));
				solicitudCreacion.setMoneda(new Moneda(Long.valueOf(resultSet.getString("ID_MONEDA")),resultSet.getString("MONEDA")));
				solicitudCreacion.setTipoCuenta(new TipoCuenta(Long.valueOf(resultSet.getString("ID_TIPOCUENTA")),resultSet.getString("TIPOCUENTA")));
				solicitudCreacionList.add(solicitudCreacion);
			}
		} catch (SQLException e) {
			logger.error(e, e.fillInStackTrace());
			throw new DomainException(e);
		}
		close(resultSet);
		return solicitudCreacionList;
	}

	@Override
	public List<SolicitudCreacion> listarSolicitudCreacionPorEmpresa(
			BigInteger codigoEmpresa) throws DomainException {

		CallableStatement cal =invokeStoreProcedureCallable(USP_LIS_SOLIC_CREAC_EMPRESA, codigoEmpresa+"", new OutParameter(OracleTypes.CURSOR));
		ResultSet resultSet=null;
		List<SolicitudCreacion> solicitudCreacionList = new ArrayList<SolicitudCreacion>();
		 
		try {
			resultSet = (ResultSet) cal.getObject(2);
			while (resultSet.next()) { 
				SolicitudCreacion solicitudCreacion=new SolicitudCreacion();	
				solicitudCreacion.setIdSolicitudCreacion(resultSet.getLong("ID_SOLICITUDCREACION"));
				solicitudCreacion.setEstado(resultSet.getString("ESTADO"));
				solicitudCreacion.setFechaCreacion(resultSet.getDate("FECHACREACION")); 
				solicitudCreacion.setFechaEjecucionbf(resultSet.getDate("FECHAEJECUCIONBF"));
				solicitudCreacion.setNombreArchivo(resultSet.getString("NOMBREARCHIVO"));
				solicitudCreacion.setUsuarioCreacion(resultSet.getString("USUARIOCREACION"));
				solicitudCreacion.setMoneda(new Moneda(Long.valueOf(resultSet.getString("ID_MONEDA")),resultSet.getString("MONEDA")));
				solicitudCreacion.setTipoCuenta(new TipoCuenta(Long.valueOf(resultSet.getString("ID_TIPOCUENTA")),resultSet.getString("TIPOCUENTA")));
				solicitudCreacionList.add(solicitudCreacion);
				
			}
		} catch (SQLException e) {
			logger.error(e, e.fillInStackTrace());
			throw new DomainException(e);
		}finally{
			try {
				cal.getConnection().close();
				cal.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
		return solicitudCreacionList;
	}

	@Override
	public List<Empleado> listarDetalleSolicitudCreacion(
			BigInteger codigoEmpresa, BigInteger codigoSolicitudCreacion)
			throws DomainException {
		ResultSet resultSet=null;
		CallableStatement cal =invokeStoreProcedureCallable(
				USP_LIS_DET_SOLIC_CREACION, codigoEmpresa.longValue()+"",
				codigoSolicitudCreacion.longValue()+"", new OutParameter(OracleTypes.CURSOR));
		List<Empleado> empleadoList = new ArrayList<Empleado>();
		
		try {
			resultSet = (ResultSet) cal.getObject(3);
			while (resultSet.next()) {
				Empleado empleado=new Empleado(); 
				TipoDocumento tipoDocumento=new TipoDocumento();
				empleado.setIdEmpleado(resultSet.getLong("ID_EMPLEADO"));
				tipoDocumento.setIdTipodocumento(resultSet.getLong("ID_TIPODOCUMENTO"));
				tipoDocumento.setDescripcion(resultSet.getString("TIPODOCUMENTO"));
				//llamar a select tipodoc
				empleado.setTipodocumento(tipoDocumento);
				empleado.setNrodocumento(resultSet.getString("NRODOCUMENTO"));
				empleado.setNrocuenta(resultSet.getString("NROCUENTA"));
				Moneda moneda=new Moneda();
				moneda.setIdMoneda(resultSet.getInt("ID_MONEDA"));
				moneda.setDescripcion(resultSet.getString("MONEDA"));
				//llamar a select moneda
				empleado.setMoneda(moneda);
				empleado.setApellidonombre(resultSet.getString("APELLIDONOMBRE"));
				empleado.setEstado(resultSet.getString("ESTADO"));
				empleado.setFechanacimiento(resultSet.getDate("FECHANACIMIENTO")); 
				empleadoList.add(empleado);
			}
		} catch (SQLException e) {
			e.printStackTrace();
			logger.error(e, e.fillInStackTrace());
			throw new DomainException(e);
		}finally{
			try {
				cal.getConnection().close();
				cal.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return empleadoList;	
		}
		
	}


	
	
 
	

}
